import requests
from bs4 import BeautifulSoup
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog, simpledialog
from PIL import Image, ImageTk
import io
import threading
import re
import os

class WebContentViewer:
    def __init__(self, root):
        self.root = root
        self.root.title("网页内容提取器")
        self.root.geometry("1200x700")
        self.root.minsize(1000, 700)

        self.current_cookies = ''
        # 默认用户代理
        self.default_user_agents = [
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/113.0',
            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15',
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/113.0.1774.57'
        ]
        self.current_user_agent = self.default_user_agents[0]

        # 预设的 Accept-Language 选项
        self.default_accept_languages = [
            'zh-CN,zh;q=0.9',  # 简体中文优先
            'en-US,en;q=0.9',  # 英文优先
            'ja-JP,ja;q=0.9,zh-CN,zh;q=0.8,en;q=0.7',  # 日文优先，其次简中，最后英文
            'ko-KR,ko;q=0.9,zh-CN,zh;q=0.8,en;q=0.7',  # 韩文优先，其次简中，最后英文
            'zh-TW,zh;q=0.9,en;q=0.8',  # 繁体中文优先，其次英文
        ]
        self.current_accept_language = self.default_accept_languages[0]  # 默认使用简体中文
        
        # 设置中文字体支持
        self.style = ttk.Style()
        self.style.configure("TLabel", font=("SimHei", 10))
        self.style.configure("TButton", font=("SimHei", 10))
        self.style.configure("TEntry", font=("SimHei", 10))
        self.style.configure("TText", font=("SimHei", 10))
        
        # 创建主框架
        self.main_frame = ttk.Frame(root, padding="10")
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建输入区域
        self.create_input_frame()
        
        # 创建结果显示区域
        self.create_result_frame()
        
        # 状态变量
        self.is_extracting = False
        self.extracted_items = []
        self.current_page = 1  # 用于分页显示
        self.items_per_page = 20  # 4列x5行=20项/页

    def create_input_frame(self):
        input_frame = ttk.LabelFrame(self.main_frame, text="搜索设置", padding="10")
        input_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 第一行：URL前缀和页面前缀
        ttk.Label(input_frame, text="搜索URL前缀:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.url_prefix_var = tk.StringVar(value="https://avfan.com/search?q=")
        ttk.Entry(input_frame, textvariable=self.url_prefix_var, width=50).grid(row=0, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(input_frame, text="页面前缀:").grid(row=0, column=2, sticky=tk.W, pady=5, padx=(10,0))
        self.page_prefix_var = tk.StringVar(value="&page=")
        ttk.Entry(input_frame, textvariable=self.page_prefix_var, width=10).grid(row=0, column=3, sticky=tk.W, pady=5)
        
        # 用户代理设置按钮
        self.ua_btn = ttk.Button(input_frame, text="设置用户代理", command=self.set_user_agent)
        self.ua_btn.grid(row=0, column=4, padx=10, pady=5)
        
        # 第二行：关键词和元素class
        ttk.Label(input_frame, text="关键词 (用逗号分隔):").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.keywords_var = tk.StringVar(value="heyzo")
        ttk.Entry(input_frame, textvariable=self.keywords_var, width=50).grid(row=1, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(input_frame, text="元素Class:").grid(row=1, column=2, sticky=tk.W, pady=5, padx=(10,0))
        self.class_var = tk.StringVar(value="flex flex-col relative hover:bg-zinc-100 hover:dark:bg-zinc-800")
        ttk.Entry(input_frame, textvariable=self.class_var, width=30).grid(row=1, column=3, sticky=tk.W, pady=5)


        # 第三行：页码范围和按钮
        ttk.Label(input_frame, text="开始页码:").grid(row=2, column=0, sticky=tk.W, pady=5)
        self.start_page_var = tk.StringVar(value="1")
        ttk.Entry(input_frame, textvariable=self.start_page_var, width=10).grid(row=2, column=1, sticky=tk.W, pady=5)
        
        ttk.Label(input_frame, text="结束页码:").grid(row=2, column=2, sticky=tk.W, pady=5, padx=(10,0))
        self.end_page_var = tk.StringVar(value="1")
        ttk.Entry(input_frame, textvariable=self.end_page_var, width=10).grid(row=2, column=3, sticky=tk.W, pady=5)
        
        # 按钮
        button_frame = ttk.Frame(input_frame)
        button_frame.grid(row=2, column=4, padx=10)
        # 在第二行添加Accept-Language设置
        ttk.Label(input_frame, text="Accept-Language:").grid(row=1, column=4, sticky=tk.W, pady=5, padx=(10, 0))  # 新增
        self.accept_language_var = tk.StringVar(value=self.current_accept_language)  # 新增
        ttk.Entry(input_frame, textvariable=self.accept_language_var, width=20).grid(row=1, column=5, sticky=tk.W,
                                                                                     pady=5)  # 新增

        # 第三行添加Cookies输入框
        ttk.Label(input_frame, text="Cookies:").grid(row=2, column=4, sticky=tk.W, pady=5, padx=(10, 0))  # 新增
        self.cookies_var = tk.StringVar(value=self.current_cookies)  # 新增
        ttk.Entry(input_frame, textvariable=self.cookies_var, width=40).grid(row=2, column=5, sticky=tk.W, pady=5)  # 新增

        # 调整按钮框架的网格位置（原代码修改）
        button_frame.grid(row=2, column=6, padx=10)  # 修改column值

        # 调整网格权重（原代码修改）
        input_frame.grid_columnconfigure(5, weight=1)  # 新增
        input_frame.grid_columnconfigure(6, weight=1)  # 修改原4为6
        self.extract_btn = ttk.Button(button_frame, text="开始提取", command=self.start_extraction)
        self.extract_btn.pack(side=tk.LEFT, padx=5)
        
        self.save_btn = ttk.Button(button_frame, text="保存结果", command=self.save_results, state=tk.DISABLED)
        self.save_btn.pack(side=tk.LEFT, padx=5)
        
        # 添加网格权重，使界面可伸缩
        input_frame.grid_columnconfigure(1, weight=1)
        input_frame.grid_columnconfigure(3, weight=1)
        input_frame.grid_columnconfigure(4, weight=1)

    def create_result_frame(self):
        # 创建结果显示区域
        result_frame = ttk.LabelFrame(self.main_frame, text="提取结果", padding="10")
        result_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建一个带滚动条的画布，用于显示网格布局的图片和标题
        self.canvas = tk.Canvas(result_frame)
        
        # 垂直滚动条
        vscrollbar = ttk.Scrollbar(result_frame, orient=tk.VERTICAL, command=self.canvas.yview)
        vscrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 水平滚动条
        hscrollbar = ttk.Scrollbar(result_frame, orient=tk.HORIZONTAL, command=self.canvas.xview)
        hscrollbar.pack(side=tk.BOTTOM, fill=tk.X)
        
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.canvas.configure(yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set)
        
        # 创建用于放置图片和标题的框架
        self.grid_frame = ttk.Frame(self.canvas)
        self.canvas_frame = self.canvas.create_window((0, 0), window=self.grid_frame, anchor="nw")
        
        # 绑定事件以更新滚动区域
        self.grid_frame.bind("<Configure>", self.on_grid_configure)
        self.canvas.bind("<Configure>", self.on_canvas_configure)
        
        # 分页控制区域
        pagination_frame = ttk.Frame(result_frame)
        pagination_frame.pack(fill=tk.X, pady=5)
        
        self.prev_btn = ttk.Button(pagination_frame, text="上一页", command=self.prev_page, state=tk.DISABLED)
        self.prev_btn.pack(side=tk.LEFT, padx=5)
        
        self.page_label = ttk.Label(pagination_frame, text="第 1 页")
        self.page_label.pack(side=tk.LEFT, padx=5)
        
        self.next_btn = ttk.Button(pagination_frame, text="下一页", command=self.next_page, state=tk.DISABLED)
        self.next_btn.pack(side=tk.LEFT, padx=5)
        
        # 状态区域
        self.status_var = tk.StringVar(value="就绪")
        self.status_bar = ttk.Label(self.main_frame, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

    def on_grid_configure(self, event):
        # 更新画布滚动区域
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def on_canvas_configure(self, event):
        # 当画布大小改变时，调整内部框架宽度
        self.canvas.itemconfig(self.canvas_frame, width=event.width)

    def set_user_agent(self):
        """设置用户代理"""
        # 创建一个对话框供用户选择或输入用户代理
        dialog = tk.Toplevel(self.root)
        dialog.title("设置用户代理")
        dialog.geometry("600x400")
        dialog.transient(self.root)
        dialog.grab_set()
        
        ttk.Label(dialog, text="选择或输入用户代理:").pack(pady=10, anchor=tk.W, padx=10)
        
        # 列表框显示预设的用户代理
        frame = ttk.Frame(dialog)
        frame.pack(fill=tk.BOTH, expand=True, padx=10)
        
        listbox = tk.Listbox(frame, font=("SimHei", 10), selectmode=tk.SINGLE)
        scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=listbox.yview)
        listbox.configure(yscrollcommand=scrollbar.set)
        
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 添加预设用户代理
        for ua in self.default_user_agents:
            listbox.insert(tk.END, ua)
        
        # 选中当前使用的用户代理
        try:
            index = self.default_user_agents.index(self.current_user_agent)
            listbox.selection_set(index)
            listbox.see(index)
        except ValueError:
            pass
        
        # 自定义用户代理输入框
        ttk.Label(dialog, text="或输入自定义用户代理:").pack(pady=5, anchor=tk.W, padx=10)
        ua_entry = ttk.Entry(dialog, width=80)
        ua_entry.pack(fill=tk.X, padx=10, pady=5)
        ua_entry.insert(0, self.current_user_agent)
        
        # 确认按钮
        def confirm():
            nonlocal listbox, ua_entry, dialog
            # 检查列表框是否有选中项
            selected = listbox.curselection()
            if selected:
                self.current_user_agent = listbox.get(selected[0])
                ua_entry.delete(0, tk.END)
                ua_entry.insert(0, self.current_user_agent)
            else:
                # 使用输入框中的值
                custom_ua = ua_entry.get().strip()
                if custom_ua:
                    self.current_user_agent = custom_ua
            
            self.status_var.set(f"已设置用户代理: {self.current_user_agent[:50]}...")
            dialog.destroy()
        
        btn_frame = ttk.Frame(dialog)
        btn_frame.pack(pady=10)
        
        ttk.Button(btn_frame, text="确认", command=confirm).pack(side=tk.LEFT, padx=10)
        ttk.Button(btn_frame, text="取消", command=dialog.destroy).pack(side=tk.LEFT, padx=10)
        
        # 绑定双击事件
        listbox.bind("<Double-1>", lambda e: confirm())

    def start_extraction(self):
        # 检查是否正在提取
        if self.is_extracting:
            messagebox.showinfo("提示", "正在提取内容，请等待完成")
            return
            
        # 清空之前的结果
        self.clear_grid()
        self.extracted_items = []
        self.current_page = 1
        self.save_btn.config(state=tk.DISABLED)
        self.update_pagination_buttons()
        
        # 获取输入值
        try:
            url_prefix = self.url_prefix_var.get().strip()
            page_prefix = self.page_prefix_var.get().strip()
            keywords_input = self.keywords_var.get().strip()
            class_name = self.class_var.get().strip()
            start_page = int(self.start_page_var.get().strip())
            end_page = int(self.end_page_var.get().strip())
            
            # 验证输入
            if not url_prefix:
                messagebox.showerror("错误", "请输入搜索URL前缀")
                return
                
            if not re.match(r'^https?://', url_prefix):
                messagebox.showerror("错误", "URL前缀必须以http://或https://开头")
                return
                
            if not page_prefix:
                messagebox.showerror("错误", "请输入页面前缀")
                return
                
            if not keywords_input:
                messagebox.showerror("错误", "请输入关键词")
                return
                
            if not class_name:
                messagebox.showerror("错误", "请输入元素Class")
                return
                
            if start_page <= 0 or end_page < start_page:
                messagebox.showerror("错误", "页码输入错误，请确保开始页码大于0且结束页码不小于开始页码")
                return
                
        except ValueError:
            messagebox.showerror("错误", "请输入有效的页码")
            return
            
        # 拆分关键词
        keywords = [kw.strip() for kw in keywords_input.split(",") if kw.strip()]
        main_keyword = keywords[0]
        filter_keywords = keywords[1:]
        
        # 禁用按钮
        self.extract_btn.config(state=tk.DISABLED)
        self.is_extracting = True
        self.status_var.set("正在提取内容...")
        
        # 在新线程中执行提取，避免界面冻结
        threading.Thread(target=self.perform_extraction, args=(
            url_prefix, page_prefix, main_keyword, filter_keywords, 
            class_name, start_page, end_page
        ), daemon=True).start()

    def perform_extraction(self, url_prefix, page_prefix, main_keyword, filter_keywords, class_name, start_page, end_page):
        try:
            no_result_counter = 0  # 连续无结果计数器
            # 构建基础URL
            base_url = f"{url_prefix}{main_keyword}"
            
            # 处理每个页面
            for page in range(start_page, end_page + 1):
                # 更新状态
                self.root.after(0, lambda p=page: self.status_var.set(f"正在处理第 {p} 页..."))
                
                # 构建完整URL
                url = f"{base_url}{page_prefix}{page}"
                
                # 获取网页内容
                success, content = self.get_web_content(url)
                
                if success:
                    # 提取元素
                    elements = self.extract_elements_with_class(content, class_name)
                    
                    if elements:
                        no_result_counter = 0
                        # 筛选元素
                        filtered_elements = []
                        for elem in elements:
                            title_tags = elem.find_all(attrs={"title": True})
                            if title_tags:
                                # 获取title
                                elem_title = list({tag['title'] for tag in title_tags})[0]
                                
                                # 检查筛选关键词
                                if all(keyword.lower() in elem_title.lower() for keyword in filter_keywords):
                                    # 查找图片
                                    img_src = None
                                    img_tags = elem.find_all('img', attrs={"src": True})
                                    if img_tags:
                                        img_src = img_tags[0]['src']
                                        # 处理相对路径
                                        if not img_src.startswith(('http://', 'https://')):
                                            # 提取基础URL
                                            base_domain = re.match(r'^https?://[^/]+', url_prefix).group(0)
                                            img_src = f"{base_domain}{img_src}" if img_src.startswith('/') else f"{base_domain}/{img_src}"
                                    
                                    filtered_elements.append({
                                        'title': elem_title,
                                        'img_src': img_src,
                                        'page': page
                                    })
                        
                        # 添加到结果列表
                        self.extracted_items.extend(filtered_elements)
                        
                        # 更新状态
                        self.root.after(0, lambda p=page, c=len(filtered_elements): 
                                      self.status_var.set(f"第 {p} 页处理完成，找到 {c} 个匹配元素"))
                    else:
                        # 无结果时增加计数器
                        no_result_counter += 1
                        self.root.after(0, lambda p=page:
                        self.status_var.set(f"第 {p} 页未找到匹配的元素"))

                        # 如果连续2页无结果，停止查找
                        if no_result_counter >= 2:
                            self.root.after(0, lambda:
                            self.status_var.set(f"连续2页未找到结果，已停止查找"))
                            break  # 退出循环，停止翻页
                else:
                    self.root.after(0, lambda p=page, e=content: 
                                  self.status_var.set(f"第 {p} 页错误: {e}"))
            
            # 提取完成，显示第一页结果
            self.root.after(0, self.display_current_page)
            self.root.after(0, lambda: self.status_var.set(f"提取完成，共找到 {len(self.extracted_items)} 个元素"))
            self.root.after(0, lambda: self.save_btn.config(state=tk.NORMAL))
            self.root.after(0, self.update_pagination_buttons)
            
        except Exception as e:
            self.root.after(0, lambda: self.status_var.set(f"提取过程中发生错误: {str(e)}"))
        finally:
            # 恢复按钮状态
            self.root.after(0, lambda: self.extract_btn.config(state=tk.NORMAL))
            self.is_extracting = False

    def clear_grid(self):
        """清空网格中的所有内容"""
        for widget in self.grid_frame.winfo_children():
            widget.destroy()

    def display_current_page(self):
        """显示当前页的内容，4列5行布局"""
        self.clear_grid()
        
        if not self.extracted_items:
            ttk.Label(self.grid_frame, text="没有找到匹配的内容").grid(row=0, column=0, padx=10, pady=10)
            return
            
        # 计算当前页显示的项目范围
        start_idx = (self.current_page - 1) * self.items_per_page
        end_idx = min(start_idx + self.items_per_page, len(self.extracted_items))
        current_items = self.extracted_items[start_idx:end_idx]
        
        # 更新页码标签
        total_pages = (len(self.extracted_items) + self.items_per_page - 1) // self.items_per_page
        self.page_label.config(text=f"第 {self.current_page} 页 / 共 {total_pages} 页")
        
        # 网格布局：4列5行
        cols = 4
        row = 0
        col = 0
        
        for i, item in enumerate(current_items):
            # 创建每个项目的框架
            item_frame = ttk.Frame(self.grid_frame, padding=5)
            item_frame.grid(row=row, column=col, padx=10, pady=10, sticky=tk.NSEW)
            
            # 图片标签
            img_label = ttk.Label(item_frame, text="加载图片中...")
            img_label.pack(pady=(0, 5))
            
            # 标题标签（自动换行）
            title_label = ttk.Label(
                item_frame, 
                text=item['title'], 
                wraplength=200,  # 限制宽度，超出自动换行
                justify=tk.LEFT
            )
            title_label.pack()
            
            # 在新线程中加载图片
            threading.Thread(target=self.load_image, args=(item['img_src'], img_label), daemon=True).start()
            
            # 更新行列位置
            col += 1
            if col >= cols:
                col = 0
                row += 1
        
        # 设置网格权重，使项目均匀分布
        for c in range(cols):
            self.grid_frame.grid_columnconfigure(c, weight=1)
        for r in range(row + 1):
            self.grid_frame.grid_rowconfigure(r, weight=1)

    def update_pagination_buttons(self):
        """更新分页按钮状态"""
        total_pages = (len(self.extracted_items) + self.items_per_page - 1) // self.items_per_page
        
        if total_pages <= 1:
            self.prev_btn.config(state=tk.DISABLED)
            self.next_btn.config(state=tk.DISABLED)
        else:
            self.prev_btn.config(state=tk.NORMAL if self.current_page > 1 else tk.DISABLED)
            self.next_btn.config(state=tk.NORMAL if self.current_page < total_pages else tk.DISABLED)

    def prev_page(self):
        """显示上一页"""
        if self.current_page > 1:
            self.current_page -= 1
            self.display_current_page()
            self.update_pagination_buttons()

    def next_page(self):
        """显示下一页"""
        total_pages = (len(self.extracted_items) + self.items_per_page - 1) // self.items_per_page
        if self.current_page < total_pages:
            self.current_page += 1
            self.display_current_page()
            self.update_pagination_buttons()

    def load_image(self, img_src, label):
        """加载图片并显示"""
        if not img_src:
            self.root.after(0, lambda: label.config(text="没有图片可用"))
            return
            
        try:
            # 下载图片
            headers = {
                'User-Agent': self.current_user_agent,
                'Accept-Language': 'zh-CN,zh;q=0.9'
            }
            response = requests.get(img_src, headers=headers, timeout=10)
            response.raise_for_status()
            
            # 处理图片
            image = Image.open(io.BytesIO(response.content))
            
            # 调整图片大小，保持比例
            max_size = (200, 200)
            image.thumbnail(max_size, Image.LANCZOS)
            
            # 转换为Tkinter可用格式
            tk_image = ImageTk.PhotoImage(image)
            
            # 更新界面
            self.root.after(0, lambda: label.config(image=tk_image, text=""))
            # 保持引用，防止被垃圾回收
            self.root.after(0, lambda: setattr(label, "image", tk_image))
            
        except Exception as e:
            self.root.after(0, lambda: label.config(text=f"无法加载图片\n{str(e)[:20]}..."))

    def save_results(self):
        if not self.extracted_items:
            messagebox.showinfo("提示", "没有可保存的结果")
            return
            
        # 询问保存位置
        file_path = filedialog.asksaveasfilename(
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")],
            title="保存结果"
        )
        
        if not file_path:
            return
            
        try:
            with open(file_path, "w", encoding="utf-8") as f:
                f.write("网页内容提取结果\n")
                f.write("=" * 50 + "\n\n")
                
                for i, item in enumerate(self.extracted_items, 1):
                    f.write(f"项目 {i}:\n")
                    f.write(f"标题: {item['title']}\n")
                    f.write(f"图片URL: {item['img_src'] or '无'}\n")
                    f.write(f"来源页面: {item['page']}\n")
                    f.write("-" * 50 + "\n")
            
            messagebox.showinfo("成功", f"结果已保存到: {file_path}")
            self.status_var.set(f"结果已保存到: {file_path}")
            
        except Exception as e:
            messagebox.showerror("错误", f"保存文件时出错: {str(e)}")
            self.status_var.set(f"保存文件失败: {str(e)}")

    def get_web_content(self, url):
        """获取指定URL的网页内容"""
        try:
            # 使用当前设置的用户代理
            headers = {
                'User-Agent': self.current_user_agent,
                'Accept-Language': self.current_accept_language,
                #'Cookie': 'Bearer _ga=GA1.1.124818105.1756016991; legal_age=1; locale=zh-CN; _rucaptcha_session_id=4120c2db9d24fb5b2a21f4de44b6b9dd; cf_clearance=EpGP.j_0LYlLVBOIURk8Ni6nOpjmEC08ijMmAjE5fxE-1756114219-1.2.1.1-AfKlqMapPTL20sus1s6oM8WNn6ORh62KwZip6vZWCxEf0eg_P0L36_BrJ5VXqkRWYiBRcdp3INZWJPjjxzXiEloriLPgsjum.AgXaqfyD4K4HahUHwsrHH6NLLiP97ux7Zr3Hu3snvgkSzoZ662c.4rg4i61J1OlCNNet.bPSfrKegaHjoPtDKZof7GsIbd2cVaIi.Q0oJVHzWf8_TkPNiu2B0Slbjnm3RGABSGQl1Q; remember_token=eyJfcmFpbHMiOnsibWVzc2FnZSI6IklqUTNNbVJqT0Rjek9HVXhNRFZoTVRZNU5qbGtNMk5pWkRNM01XRmhObU00WWpJeU5UUmxObVVpIiwiZXhwIjoiMjAyNi0wOC0yNVQwOTozOTozMy42ODNaIiwicHVyIjoiY29va2llLnJlbWVtYmVyX3Rva2VuIn19--035b3679561c553a1fc1aca9e387b5ed35a92d40; sess_af=2HqrWQwXga8WO0glf2SUVqF79V7orqsyYgRlAmoAwnfH%2BMQyWZeE5mHwVig2wR6s73MU6LsdkewsokrVQJH9q9oly%2F%2F3j0EiR37I80azb6h7LU8E9cBWDHXCrB6tP7zwZk9eHj%2FYwog5dy%2BWgY99AWc1z9tFHwx34cOhIF21W4tpephrKx%2F0FGeAE8k1KEkE9D%2BO7Gl8bKqNlWPeek3ZLykPlM5FyNJ%2FT9TsNKuCyiXsi6fc1f27TtbHlZsuHdSJGwvU5C4D%2FDxpXpTr7vanZchreCDsQMW369GM3RWEM0FpB6welQ%3D%3D--z4ENKmdMxhcLn5MV--kZM5QcSONsGNlypc%2B3w2fA%3D%3D; _ga_3VWHT3ZLEW=GS2.1.s1756110234$o3$g1$t1756114775$j39$l0$h0'
                'Cookie': self.cookies_var.get()  # 修改为从输入框获取
            }

            # 发送GET请求
            response = requests.get(url, headers=headers, timeout=10)

            # 检查请求是否成功
            response.raise_for_status()

            # 设置正确的编码
            response.encoding = response.apparent_encoding

            return True, response.text

        except requests.exceptions.MissingSchema:
            return False, "URL格式错误，请确保包含http://或https://"
        except requests.exceptions.ConnectionError:
            return False, "连接错误，无法连接到服务器"
        except requests.exceptions.Timeout:
            return False, "请求超时"
        except requests.exceptions.HTTPError as e:
            return False, f"HTTP错误: {str(e)}"
        except Exception as e:
            return False, f"发生错误: {str(e)}"

    def extract_elements_with_class(self, html_content, class_name):
        """从HTML内容中提取指定类的元素"""
        soup = BeautifulSoup(html_content, 'html.parser')
        # 查找所有具有指定class的元素
        elements = soup.find_all(class_=class_name)
        return elements

if __name__ == "__main__":
    # 确保中文显示正常
    root = tk.Tk()
    app = WebContentViewer(root)
    root.mainloop()
    